﻿using OnWork.Admin.DAL;
using SqlSugar;

namespace OnWork.Admin.BLL
{
    public class BaseBLL
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sqlSugarScope"></param>
        public BaseBLL(SqlSugarScope sqlSugarScope)
        {
            db = sqlSugarScope;
        }

        /// <summary>
        /// DB数据库
        /// </summary>
        protected SqlSugarScope db;

        /// <summary>
        /// 当前用户ID
        /// </summary>
        public long currentUserId = 0;

        /// <summary>
        /// 数据插入
        /// </summary>
        /// <param name="obj"></param>
        public long Add<T>(T obj) where T : BaseEntity, new()
        {
            obj.CreateId = currentUserId;
            obj.UpdateId = currentUserId;
            obj.CreateTime = DateTime.Now;
            obj.UpdateTime = DateTime.Now;
            obj.IsDel = false;
            return db.Insertable(obj).ExecuteReturnSnowflakeId();//单条插入返回雪花ID
        }

        /// <summary>
        /// 数据添加异步 方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns>插入的ID</returns>
        public Task<long> AddAsync<T>(T obj) where T : BaseEntity, new()
        {
            obj.CreateId = currentUserId;
            obj.UpdateId = currentUserId;
            obj.CreateTime = DateTime.Now;
            obj.UpdateTime = DateTime.Now;
            obj.IsDel = false;
            return db.Insertable(obj).ExecuteReturnSnowflakeIdAsync();//单条插入返回雪花ID
        }

        /// <summary>
        /// 数据添加分表 异步 方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns>插入的ID</returns>
        public Task<long> AddSplitTableAsync<T>(T obj) where T : BaseEntity, new()
        {
            obj.CreateId = currentUserId;
            obj.UpdateId = currentUserId;
            obj.CreateTime = DateTime.Now;
            obj.UpdateTime = DateTime.Now;
            obj.IsDel = false;
            return db.Insertable(obj).SplitTable().ExecuteReturnSnowflakeIdAsync();//单条插入返回雪花ID
        }

        /// <summary>
        /// 数据添加分表 异步 方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns>插入的ID</returns>
        public long AddSplitTable<T>(T obj) where T : BaseEntity, new()
        {
            obj.CreateId = currentUserId;
            obj.UpdateId = currentUserId;
            obj.CreateTime = DateTime.Now;
            obj.UpdateTime = DateTime.Now;
            obj.IsDel = false;
            return db.Insertable(obj).SplitTable().ExecuteReturnSnowflakeId();//单条插入返回雪花ID
        }

        /// <summary>
        /// 数据插入
        /// </summary>
        /// <param name="obj"></param>
        public List<long> Add<T>(List<T> list) where T : BaseEntity, new()
        {
            foreach (var obj in list)
            {
                obj.CreateId = currentUserId;
                obj.UpdateId = currentUserId;
                obj.CreateTime = DateTime.Now;
                obj.UpdateTime = DateTime.Now;
                obj.IsDel = false;
            }
            return db.Insertable(list).ExecuteReturnSnowflakeIdList();//单条插入返回雪花ID
        }

        /// <summary>
        /// 数据插入
        /// </summary>
        /// <param name="obj"></param>
        public Task<List<long>> AddAsync<T>(List<T> list) where T : BaseEntity, new()
        {
            foreach (var obj in list)
            {
                obj.CreateId = currentUserId;
                obj.UpdateId = currentUserId;
                obj.CreateTime = DateTime.Now;
                obj.UpdateTime = DateTime.Now;
                obj.IsDel = false;
            }
            return db.Insertable(list).ExecuteReturnSnowflakeIdListAsync();//单条插入返回雪花ID
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="obj"></param>
        public int Update<T>(T obj) where T : BaseEntity, new()
        {
            obj.UpdateId = currentUserId;
            obj.UpdateTime = DateTime.Now;
            return db.Updateable(obj).IgnoreColumns(x => new { x.CreateTime, x.CreateId }).ExecuteCommand();
        }

        /// <summary>
        /// 更新异步
        /// </summary>
        /// <param name="obj"></param>
        public Task<int> UpdateAsync<T>(T obj) where T : BaseEntity, new()
        {
            obj.UpdateId = currentUserId;
            obj.UpdateTime = DateTime.Now;
            return db.Updateable(obj).IgnoreColumns(x => new { x.CreateTime, x.CreateId }).ExecuteCommandAsync();
        }

        /// <summary>
        /// 更新批量
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int Update<T>(List<T> list) where T : BaseEntity, new()
        {
            foreach (var obj in list)
            {
                obj.UpdateId = currentUserId;
                obj.UpdateTime = DateTime.Now;
            }
            return db.Updateable(list).IgnoreColumns(x => new { x.CreateTime, x.CreateId }).ExecuteCommand();
        }

        /// <summary>
        /// 更新批量
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public Task<int> UpdateAsync<T>(List<T> list) where T : BaseEntity, new()
        {
            foreach (var obj in list)
            {
                obj.UpdateId = currentUserId;
                obj.UpdateTime = DateTime.Now;
            }
            return db.Updateable(list).IgnoreColumns(x => new { x.CreateTime, x.CreateId }).ExecuteCommandAsync();
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="obj"></param>
        public int Delete<T>(T obj) where T : BaseEntity, new()
        {
            obj.UpdateId = currentUserId;
            obj.UpdateTime = DateTime.Now;
            obj.IsDel = true;
            return db.Updateable(obj).ExecuteCommand();
        }

        /// <summary>
        /// 删除异步 假删除
        /// </summary>
        /// <param name="obj"></param>
        public Task<int> DeleteAsync<T>(T obj) where T : BaseEntity, new()
        {
            obj.UpdateId = currentUserId;
            obj.UpdateTime = DateTime.Now;
            obj.IsDel = true;
            return db.Updateable(obj).ExecuteCommandAsync();
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="obj"></param>
        public int Delete<T>(List<T> list) where T : BaseEntity, new()
        {
            foreach (var obj in list)
            {
                obj.UpdateId = currentUserId;
                obj.UpdateTime = DateTime.Now;
                obj.IsDel = true;
            }
            return db.Updateable(list).ExecuteCommand();
        }

        /// <summary>
        /// 删除的异步方法 假删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public Task<int> DeleteAsync<T>(List<T> list) where T : BaseEntity, new()
        {
            foreach (var obj in list)
            {
                obj.UpdateId = currentUserId;
                obj.UpdateTime = DateTime.Now;
                obj.IsDel = true;
            }
            return db.Updateable(list).ExecuteCommandAsync();
        }

        /// <summary>
        /// 删除的异步方法 假删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public async Task<int> DeleteAsync<T>(long[] ids) where T : BaseEntity, new()
        {
            var list = await db.Queryable<T>().Where(x => ids.Contains(x.Id)).ToListAsync();
            foreach (var obj in list)
            {
                obj.UpdateId = currentUserId;
                obj.UpdateTime = DateTime.Now;
                obj.IsDel = true;
            }
            return await db.Updateable(list).ExecuteCommandAsync();
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <returns></returns>
        public ISugarQueryable<T> Queryable<T>() where T : BaseEntity, new()
        {
            return db.Queryable<T>().Where(x => x.IsDel == false);
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <returns></returns>
        public ISugarQueryable<T> QueryableCopy<T>() where T : BaseEntity, new()
        {
            return db.CopyNew().Queryable<T>().Where(x => x.IsDel == false);
        }
    }

    /// <summary>
    /// 泛型模式
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class BaseBLL<T> : BaseBLL where T : BaseEntity, new()
    {
        public BaseBLL(SqlSugarScope sqlSugarScope) : base(sqlSugarScope)
        {
        }

        /// <summary>
        /// 返回单个ID
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T SingleById(long id)
        {
            return db.Queryable<T>().Single(x => x.Id == id);
        }

        /// <summary>
        /// 返回单个ID
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Task<T> SingleByIdAsync(long id)
        {
            return db.Queryable<T>().SingleAsync(x => x.Id == id);
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public ISugarQueryable<T> Queryable()
        {
            return db.Queryable<T>().Where(x => x.IsDel == false);
        }

        /// <summary>
        /// 查询 复制数据连接
        /// </summary>
        /// <returns></returns>
        public ISugarQueryable<T> QueryableCopy()
        {
            return db.CopyNew().Queryable<T>().Where(x => x.IsDel == false);
        }
    }
}